package com.joolun.weixin.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.joolun.common.constant.Constants;
import com.joolun.common.corp.TenantContext;
import com.joolun.common.exception.base.BaseException;
import com.joolun.common.utils.DateUtils;
import com.joolun.system.domain.ScrmDepartment;
import com.joolun.system.domain.SysCorpConfig;
import com.joolun.system.mapper.ScrmDepartmentMapper;
import com.joolun.system.service.impl.SysCorpConfigServiceImpl;
import com.joolun.weixin.config.WxCpConfiguration;
import com.joolun.weixin.mapper.StaffDepartmentMapper;
import com.joolun.weixin.service.IScrmDepartmentService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.cp.api.WxCpDepartmentService;
import me.chanjar.weixin.cp.api.impl.WxCpDepartmentServiceImpl;
import me.chanjar.weixin.cp.bean.WxCpDepart;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 企业部门Service业务层处理
 * 
 * @author joolun
 * @date 2025-02-25
 */
@Service
@Slf4j
@AllArgsConstructor
public class ScrmDepartmentServiceImpl extends ServiceImpl<ScrmDepartmentMapper, ScrmDepartment>  implements IScrmDepartmentService {

    @Autowired
    private ScrmDepartmentMapper scrmDepartmentMapper;

    @Autowired
    private StaffDepartmentMapper staffDepartmentMapper;
    @Autowired
    private WxCpConfiguration wxCpConfiguration;

    @Autowired
    private SysCorpConfigServiceImpl sysCorpConfigService;


    /**
     * 查询企业部门
     * 
     * @param id 企业部门主键
     * @return 企业部门
     */
    @Override
    public ScrmDepartment selectScrmDepartmentById(Long id)
    {
        return scrmDepartmentMapper.selectScrmDepartmentById(id);
    }

    /**
     * 查询企业部门列表
     * 
     * @param scrmDepartment 企业部门
     * @return 企业部门
     */
    @Override
    public List<ScrmDepartment> selectScrmDepartmentList(ScrmDepartment scrmDepartment)
    {
        return scrmDepartmentMapper.selectScrmDepartmentList(scrmDepartment);
    }

    /**
     * 新增企业部门
     * 
     * @param scrmDepartment 企业部门
     * @return 结果
     */
    @Override
    public int insertScrmDepartment(ScrmDepartment scrmDepartment)
    {
        scrmDepartment.setCreateTime(DateUtils.getNowDate());

        // 系统的部门上级ID
        Long sysDeptId = scrmDepartment.getExtParentId();
        ScrmDepartment parentDeptment = getOne(Wrappers.lambdaQuery(ScrmDepartment.class).eq(ScrmDepartment::getSysDeptId,sysDeptId));
        if(parentDeptment == null){
            throw new BaseException("部门不存在");
        }
        //校验数据
       // checkExists(scrmDepartment.getExtParentId(), scrmDepartment.getExtCorpId());

        //调用企业微信接口新增部门
        if (scrmDepartment.isNeedSynToWx()) {
            // 获取主体配置
            SysCorpConfig sysCorpConfig = sysCorpConfigService.getConfig(TenantContext.getTenantId());
            WxCpDepartmentService departmentService = new WxCpDepartmentServiceImpl(wxCpConfiguration.getAddressBookWxCpService(sysCorpConfig));
            WxCpDepart depart = new WxCpDepart();
            depart.setName(scrmDepartment.getName());
            depart.setOrder(scrmDepartment.getOrder());
            depart.setParentId(parentDeptment.getExtId());
            Long extId = null;
            try {
                extId = departmentService.create(depart);
            } catch (WxErrorException e) {
                log.error("---调用企业微信新增部门失败：{}",e.getMessage());
                throw new RuntimeException(e);
            }

            scrmDepartment.setExtId(extId);
        }
        scrmDepartment.setExtCorpId(parentDeptment.getExtCorpId());
        scrmDepartment.setExtParentId(parentDeptment.getExtId());
        scrmDepartment.setStaffNum(0L);
        scrmDepartment.setStatus("0");

        scrmDepartment.setParentId(parentDeptment.getId());
        scrmDepartment.setAncestors(parentDeptment.getAncestors()+","+parentDeptment.getId());

        //入库
        scrmDepartmentMapper.insertScrmDepartment(scrmDepartment);

        return 1;
    }

    /**
     * 修改企业部门
     * 
     * @param scrmDepartment 企业部门
     * @return 结果
     */
    @Override
    public int updateScrmDepartment(ScrmDepartment scrmDepartment)
    {
        scrmDepartment.setUpdateTime(DateUtils.getNowDate());
        return scrmDepartmentMapper.updateScrmDepartment(scrmDepartment);
    }

    /**
     * 批量删除企业部门
     * 
     * @param ids 需要删除的企业部门主键
     * @return 结果
     */
    @Override
    public int deleteScrmDepartmentByIds(Long[] ids)
    {
        return scrmDepartmentMapper.deleteScrmDepartmentByIds(ids);
    }

    /**
     * 删除企业部门信息
     * 
     * @param id 企业部门主键
     * @return 结果
     */
    @Override
    public int deleteScrmDepartmentById(Long id)
    {
        return scrmDepartmentMapper.deleteScrmDepartmentById(id);
    }

    @Override
    public List<ScrmDepartment> sync(String extCorpId) throws WxErrorException {
        List<ScrmDepartment> departments = new ArrayList<>();
        if (StringUtils.isBlank(extCorpId)) {
            return departments;
        }
        // 获取主体配置
        SysCorpConfig sysCorpConfig = sysCorpConfigService.getConfig(TenantContext.getTenantId());
        //获取所有的部门信息，根部门为1
        WxCpDepartmentService departmentService = new WxCpDepartmentServiceImpl(wxCpConfiguration.getWxCpService(sysCorpConfig));
        List<WxCpDepart> remoteList = departmentService.simpleList(null);

        //依然存在的部门id
        List<Long> existsExtIds = new ArrayList<>();
        //需要修改的部门列表
        List<ScrmDepartment> updateList = new ArrayList<>();
        //需要新增的部门列表
        List<ScrmDepartment> saveList = new ArrayList<>();

        Optional.ofNullable(remoteList).orElse(new ArrayList<>()).forEach(department -> {
            // 检查本地库是否存在
            ScrmDepartment depart = getOne(new QueryWrapper<ScrmDepartment>().lambda()
                    .eq(ScrmDepartment::getExtId, department.getId())
                    .eq(ScrmDepartment::getExtCorpId, extCorpId));

            //修改
            if (depart != null) {
                // 获取单个部门详情
                try {
                    WxCpDepart wxCpDepart = departmentService.get(depart.getExtId());
                    if(wxCpDepart != null){
                        String departName = wxCpDepart.getName();
                        depart.setName(departName);
                    }
                } catch (WxErrorException e) {
                    log.error("获取企业微信部门详情失败：{}",depart.getExtId());
                    throw new RuntimeException(e);
                }
                depart.setUpdateTime(new Date());
                depart.setOrder(department.getOrder());
                depart.setExtParentId(department.getParentId());
                updateList.add(depart);
                existsExtIds.add(department.getId());
            } else {
                depart = new ScrmDepartment();
//                        .setId(UUID.get32UUID())
                depart.setExtId(department.getId());
                depart.setExtCorpId(extCorpId);
                depart.setCreateTime(new Date());
                depart.setUpdateTime(new Date());
                depart .setName(department.getId() + "");
                depart.setOrder(department.getOrder());
                depart .setExtParentId(department.getParentId());
                saveList.add(depart);
            }

        });

        //将已经不存在的部门设置为删除状态
        if (CollectionUtil.isNotEmpty(existsExtIds)) {
            update(new UpdateWrapper<ScrmDepartment>()
                    .lambda()
                    .set(ScrmDepartment::getStatus, null)
                    .eq(ScrmDepartment::getExtCorpId, extCorpId)
                    .notIn(ScrmDepartment::getExtId, existsExtIds)
            );
        } else {
            update(new UpdateWrapper<ScrmDepartment>()
                    .lambda()
                    .set(ScrmDepartment::getStatus, null)
                    .eq(ScrmDepartment::getExtCorpId, extCorpId));
        }

        //批量修改
        if (CollectionUtil.isNotEmpty(updateList)) {
            departments.addAll(updateList);
            updateBatchById(updateList);
        }
        //批量新增部门
        if (CollectionUtil.isNotEmpty(saveList)) {
            saveBatch(saveList);
            departments.addAll(saveList);
        }

        //删除不存在的部门，及用户部门关联
        List<Long> exitIds = departments.stream().map(ScrmDepartment::getId).collect(Collectors.toList());
        List<Long> allIds = Optional.ofNullable(list()).orElse(new ArrayList<>()).stream().filter(department -> extCorpId.equals(department.getExtCorpId())).map(ScrmDepartment::getId).collect(Collectors.toList());
        allIds.removeAll(exitIds);
        if (CollectionUtil.isNotEmpty(allIds)) {
//            staffDepartmentMapper.removeByDepartmentIds(allIds);
            staffDepartmentMapper.deleteBatchIds(allIds);
            removeByIds(allIds);
        }
        return departments;
    }

    @Override
    public List<Long> getChildIdList(String extCorpId, List<Long> extParentIdList) {
        return getChildIdList(extCorpId, extParentIdList, new ArrayList<>());
    }

    public List<Long> getChildIdList(String extCorpId, List<Long> extParentIdList, List<Long> childIdList) {
        if (CollectionUtil.isNotEmpty(extParentIdList)) {
            List<Long> result = this.baseMapper.queryChildIdList(extCorpId, extParentIdList);
            if (CollectionUtil.isNotEmpty(result)) {
                childIdList.addAll(result);
                // 递归调用当前方法，直至获取所有子级id集合
                getChildIdList(extCorpId, result, childIdList);
            }
        }
        childIdList.addAll(extParentIdList);
        return childIdList.stream().distinct().collect(Collectors.toList());
    }


    @Override
    public Long queryDepartmentStaffNum(String extCorpId, Long extId) {
        List<Long> extDepartmentIds = null;

        // 如果是不是根部门递归查出子部门列表
        if (!Objects.equals(1L, extId)) {
            extDepartmentIds = this.getChildIdList(extCorpId, Collections.singletonList(extId));
        }
        return staffDepartmentMapper.queryDepartmentStaffNum(extCorpId, extDepartmentIds);
    }


    @Override
    public ScrmDepartment checkExists(Long extId, String extCorpId) {
        if (extId == null) {
            return null;
        }
        ScrmDepartment department = getOne(new QueryWrapper<ScrmDepartment>().lambda()
                .eq(ScrmDepartment::getExtId, extId)
                .eq(ScrmDepartment::getExtCorpId, extCorpId)
        );
        if (department == null) {
            throw new BaseException("企微部门不存在");
        }
        return department;
    }


    @Override
    public ScrmDepartment getScrmDepartmentBySysDeptId(Long sysDeptId){
        return getOne(Wrappers.lambdaQuery(ScrmDepartment.class).eq(ScrmDepartment::getSysDeptId,sysDeptId));
    }

    @Override
    public ScrmDepartment getRootDepartment(String extCorpId) {
        String corpName = "";//corpAccreditService.getCorpNameByCorpId(extCorpId);
        ScrmDepartment department = new ScrmDepartment();
        department.setId(Constants.SYS_ROOT_DEPARTMENT);
        //staffService.count(new LambdaQueryWrapper<ScrmStaff>().eq(ScrmStaff::getExtCorpId, extCorpId))
        department.setStaffNum(1L);
        department.setName(corpName);
        department.setExtId(Constants.SYS_ROOT_DEPARTMENT);

        department.setStaffNum(1L);
        return department;
    }
}
